/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
import { globalSessionData } from "../../utils/Enum";
import { toast } from "react-toastify";
import { serverErrorHandler } from "@utils/Utils";

let prevNetworkErrorTime = 0;

const fetchApi = async (url: string, config: AxiosRequestConfig) => {
  const configs: AxiosRequestConfig = {
    url: url,
    method: config.method,
    params: config.params,
    data: config.data,
    onUploadProgress: config.onUploadProgress,
    headers: {
      [globalSessionData.restCrsfHeader]: globalSessionData.crsfToken
        ? [globalSessionData.crsfToken]
        : '""'
    }
  };

  try {
    const resp: AxiosResponse = await axios(configs as AxiosRequestConfig);
    return resp;
  } catch (error: any) {
    function errorHandelingForAbortAndStatus0() {
      var diffTime = new Date().getTime() - prevNetworkErrorTime;
      if (diffTime > 3000) {
        prevNetworkErrorTime = new Date().getTime();
        toast.error(
          "Network Connection Failure : " +
          "It seems you are not connected to the internet. Please check your internet connection and try again"
        );
      }
    }
    if (axios.isAxiosError(error)) {
      if(error.response?.status){
        switch (Number(error.response.status)) {
          case 0:
            errorHandelingForAbortAndStatus0();
            break;
          case 401:
            window.location.replace("login.jsp");
            break;
          case 403:
            serverErrorHandler(
              { responseJSON: error.response?.data },
              "You are not authorized"
            );
            window.location.replace("login.jsp");
            break;
          case 404:
            serverErrorHandler(
              { responseJSON: error.response?.data },
              "Resource not found"
            );
            break;
          case 419:
              toast.warning("Session Time Out !!");
            window.location.replace("login.jsp");
            break;
          case 500:
            serverErrorHandler(
              { responseJSON: error.response?.data },
              "Internal Server Error"
            );
            break;
          case 503:
            serverErrorHandler(
              { responseJSON: error.response?.data },
              "Service Unavailable"
            );
            break;
          case 504:
            serverErrorHandler(
              { responseJSON: error.response?.data },
              "Gateway Timeout"
            );
            break;
          default:
            break;
        }
      }
      if (error.response?.statusText != "abort") {
        errorHandelingForAbortAndStatus0();
      }
    }
    throw error;
  }
};

export { fetchApi };
